<?php

namespace  App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Interface\IdempotentCall; // 引入接口
use App\Http\Interface\Snowflake; // 引入雪花算法
use Illuminate\Support\Facades\DB;


class IdempotentCallController  extends Controller implements IdempotentCall
{ 
    //  请求id
    private String $requestId;
    
    //  请求数据
    private array $data;
    
    public function __construct($requestId = 0){
        $this->setRequestId($requestId);
    }
    
    //幂等第一次调用
    public function call($requestId = 0,$data=[]){
        //先根据请求id去表里查询数据，有则查询状态(0:处理中,1:处理完成,-1:处理失败)
        //无则直接插入表.将状态置为0，待业务处理完成后置为1或-1
        if($this->getRequestId($requestId)){
            return $this->requestFail();
        }
            return $this->requestSuccess($this->requestId,0,$data);    
    }
    
    //处理完业务后，修改状态，业务处理成功状态改为1，否则为-1，写入response_json
    public function modifyStatus($requestId,$status,$data){
        //修改状态为1
        $res = DB::table('t_idempotent_call')->where('request_id',$requestId)->update([
            'status'=>$status,
            'response_json'=>json_encode($data),
            'version'=>2,
            'update_time'=>date('Y-m-d H:i:s')
        ]);
        if($res){
            return response()->json(['code'=>'200','msg'=>'幂等数据更新成功']);
        }else{
            return response()->json(['code'=>'10011','msg'=>'幂等数据更新失败']);
        }
    }
    
    public function getRequestId($requestId){
        //从数据库查询id
        return DB::table('t_idempotent_call')->where('request_id',$requestId)->first();
    }
    public function setRequestId($requestId =  null){
        //设置请求id，如果为空则设置为雪花算发生id
        if($requestId){
            $this->requestId =  $requestId;
        }
        //雪花算法生成的id
        $snowflake = new Snowflake(1,1);
        $this->requestId = $snowflake->nextId();
    }
    //请求成功,
    public function requestSuccess($requestId,$status = 0,$data){      
     
            $res = DB::table('t_idempotent_call')->insert([
                'request_id'=>$requestId,
                'status'=>$status,       
                'request_json'=>json_encode($data),
                'response_json'=>[],
                'version'=>1,
                'create_time'=>date('Y-m-d H:i:s'),
                'update_time'=>date('Y-m-d H:i:s')
            ]);
            
            if($res){
                return  response()->json(['code'=>'200','msg'=>'幂等数据添加成功']);
            }else{
                return  response()->json(['code'=>'10010','msg'=>'幂等数据添加失败']);
            } 
         
    }
    
   //请求失败
   public  function requestFail(){
    //唯一id在数据库中已存在，表示重复提交
    return  response()->json(['code'=>'10001','msg'=>'请勿重复提交']);  
   }
    
}

/*
php artisan tinker
$data = ['status'=>0,'code'=>'200','msg'=>'sucess']
new App\Http\Controllers\IdempotentCallController()->call(null,0,$data);

new App\Http\Controllers\IdempotentCallController()->call(null,0,['code'=>'200','msg'=>'sucess']);
*/
